﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WestWorldRemake;

namespace WestWorldRemake.Messaging
{
    class MessageDispatcher
    {
        public const double SendMessageImmediately = 0.0;
        public const object NoAdditionalInfo = null;

        private const ConsoleColor color = ConsoleColor.White;
        private SortedSet<Telegram> PriorityQueue;
        private bool Discharge(BaseGameEntity pReceiver, Telegram message)
        {
            Console.ForegroundColor = color;

            if (pReceiver.HandleMessage(message)==Iffy.No)
            {
                Console.WriteLine(pReceiver.GetType() + " cannot handle message.");
            }
            else if (pReceiver.HandleMessage(message) == Iffy.NotYet)
            {
                Console.WriteLine(pReceiver.GetType() + " cannot handle message *right now*.");
                PriorityQueue.Add(message);
                return false;
            }

            return true;
        }
        private MessageDispatcher() { PriorityQueue = new SortedSet<Telegram>(); }
        private static MessageDispatcher _Instance;

        public static MessageDispatcher Instance
        {
            get
            {
                if (_Instance == null)
                    _Instance = new MessageDispatcher();
                return _Instance;
            }
        }
        public void DispatchMessage(double delay, BaseGameEntity sender, BaseGameEntity receiver, 
            Messages.BaseMessage message, object ExtraInfo)
        {
            Console.ForegroundColor = color;

            if (receiver == null)
            {
                Console.WriteLine("No receiver passed into method!");
                return;
            }

            Telegram telegram = new Telegram(DateTime.Now.AddSeconds(delay), sender, receiver, message, ExtraInfo);

            if (delay <= 0.0)
            {
                Console.WriteLine("\nInstant telegram dispatched at time: " + DateTime.Now.ToShortTimeString()
                    + " by " + sender.name + " for " + receiver.name + ". Message is " + message.Message);

                Discharge(receiver, telegram);
            }
            else
            {
                PriorityQueue.Add(telegram);
                Console.WriteLine("\n Delayed telegram from " + sender.name + " recorded at time " + DateTime.Now.ToShortTimeString()
                    + " for " + receiver.name + ". Message is " + message.Message);
            }
        }

        public void DispatchDelayedMessages()
        {
            Console.ForegroundColor = color;

            DateTime now = DateTime.Now;

            if (PriorityQueue.Count > 0)
            {
                Telegram[] tEnum = new Telegram[PriorityQueue.Count];
                PriorityQueue.CopyTo(tEnum);

                foreach (Telegram t in tEnum)
                {
                    if (t.DispatchTime > now)
                        break;
                    Console.WriteLine("\nQueued telegram ready for dispatch: Sent to " + t.Receiver.name + ". Message is " + t.Message);

                    if (Discharge(t.Receiver, t));
                        PriorityQueue.Remove(t);
                }
            }
        }
    }
}
